#include <iostream>
#include <string>
#include<filesystem>
#include <fstream> 
#include<cstdio> // 文件操作
#include <map>

using namespace std;

vector<string> vFileName;

map<string, bool> recordCpyState;

// string baseFilePath = "E:\\github\\unreal_src\\UnrealEngine\\UnrealEngine\\LICENSE.md";
// string baseFilePath = "D:\\unity\\z5\unity\\430_hw\\Runtime\\CloudWebServices\\WebRequest\\WebRequest";
   string baseFilePath = "D:\\unity\\z5\\unity\\430_hw\\Runtime\\CloudWebServices";
//string baseFilePath = "D:\\unity\\z5\\unity\\430_hw\\PlatformDependent\\OpenHarmonyPlayer\\WebRequest\\Transports";
string symbol = "\\";
ofstream allFileNameAndPath("all_file.txt", ios::trunc); // 记录下所有需要替换的文件

void VerifyPath(string in, string& out)
{
	for (auto it = in.begin(); it != in.end(); it++) {
		if (*it == '\\') { // 转义
			if (*it++ != '\\') {
				int idx = distance(in.begin(), it);
				in.insert(idx, symbol);
			}
		}
	}

	cout << in << endl;
}

// 找函数
// 形式1  void Func()
//        {

// 形式2 void Func(
//             int a, intb
//			   int c)
//             {

// 形式3 在2的基础上，多了const
bool IsAFuncHead(const string lineCmd)
{
	return true;
}


enum cmdIndex {
	Print_Cpy_Files = 0,
	Print_Add_In_Cpp = 1,      // 在cpp中添加打印
	Print_Remove_In_Cpp = 2,   // 清除cpp中的打印
	Print_Remove_All_Files = 3, // 清除所有冗余文件,还原之前的文件数量
};

// 在.cppbak文件中加入printf
void WriteLogInFile(string pathName)
{
	std::ifstream infile(pathName + "cpy", ios::app);   // 原始的cpp
	std::ofstream  outfile(pathName + "bak"); // 待加入打印的cpp

	string line;
	int lineNum = 0;

	int readyVerify = 0;

	string funcName;
	while (getline(infile, line)) {
		lineNum++;
		outfile << line;

		// if for里面不添加打印
		if (line.find("if") != line.npos || line.find("for") != line.npos) {
			outfile << "\n";
			continue;
		}
		if (line.size() == 0) { // 空行
			outfile << "\n";
			continue;
		}

		if (line.back() == ')') {
			funcName = line;
			readyVerify = lineNum;
		}

		if ((lineNum == readyVerify + 1) && line.back() == '{') {

			outfile << "\nErrorStringMsg(\" hehe "  + funcName + "\");";
		}

		outfile << "\n"; // 最后添加换行
	}

	infile.close();
	outfile.close();
}

// 存储所有文件绝对路径及名称
void ShowAllFileName(string inPath, int cmd)
{
	static int fileCnt = 0;
	if (fileCnt >= 200000) {
		cout << "Warn: 文件数量超过200000,请小心" << endl;
	}

	for (auto& i : filesystem::directory_iterator(inPath)) {
		fileCnt++;
		string filePathName = i.path().string();

		auto it = filePathName.find_last_of(".");

		string fileType = filePathName.substr(it); // 选取文件最后.后缀 类型名 cpp

		// 目前仅针对cpp中加打印
		if (fileType != ".cpp") {
			// cout << "***********   后缀名不是cpp ****** ***********:" << filePathName << endl;
			continue;
		}

		// cpp中不检查含有test的文件名
		if ((fileType.find("test") != string::npos) || 
			(fileType.find("TEST") != string::npos) || 
			(fileType.find("Test") != string::npos)) {
				continue;
		}

		if (i.is_directory()) {
			cout << "这是一个目录:" << endl;
			ShowAllFileName(filePathName, cmd);
		}
		else {
			cout << filePathName << endl;
		}

		WriteLogInFile(filePathName);

		vFileName.emplace_back(filePathName);
		allFileNameAndPath << filePathName << "\n"; // 记录下所有改名的文件 

	}
}

// 拷贝所有cpp文件为cppbak 和cpprename后缀
void CopyAllFiles(string paths, int cmd)
{
	for (auto& files : filesystem::directory_iterator(paths)) {

		if (files.is_directory()) {
			cout << "这是个目录:";

			CopyAllFiles(files.path().string(), cmd); // 继续copy
			continue;
		}

		string filePathName = files.path().string();
		auto it = filePathName.find_last_of(".");
		string fileType = filePathName.substr(it); // 选取文件最后.后缀 类型名 cpp

		// 目前仅针对cpp中加打印
		if (fileType != ".cpp") {
			continue;
		}

		string cpyCmd;

		if (cmd == Print_Add_In_Cpp) {
			cpyCmd = "copy " + files.path().string() + "bak " + files.path().string();
			system(cpyCmd.c_str()); // 将有.cppbak的换成去掉变成.cpp
			continue;
		}

		// 去掉有打印的cpp
		if (cmd == Print_Remove_In_Cpp) {
			cpyCmd = "copy " + files.path().string() + "cpy " + files.path().string();
			system(cpyCmd.c_str()); // 将有.cppcpy的换成去掉变成.cpp
			continue;
		}

		// cmd 删除冗余文件
		if (cmd == Print_Remove_All_Files) {
			cpyCmd = "del " + files.path().string() + "bak";
			system(cpyCmd.c_str()); // 将有.cppbak的换成去

			cpyCmd = "move " + files.path().string() + "cpy " + files.path().string();
			system(cpyCmd.c_str()); // 将有.cppcpy的换成去掉变成.cpp
			continue;
		}


		// 文件存在并且标志为true
		bool isCpyed = recordCpyState.contains(files.path().string()) &&
			recordCpyState[files.path().string()];


		if (!isCpyed) {
			// 如果没有备份，则需要备份
			cpyCmd = "copy " + files.path().string() + " " + files.path().string() + "bak"; // 待修改的文件后缀
			system(cpyCmd.c_str());

			cpyCmd = "copy " + files.path().string() + " " + files.path().string() + "cpy"; // 待备份的文件后缀
			system(cpyCmd.c_str());
			WriteLogInFile(files.path().string());

			recordCpyState[files.path().string()] = true; // 已经拷贝的设置为true
		}
	}
}


int main(int argc, char* argv[])
{

	cout << "********* 0 :" << "拷贝文件,注意如果存在bak或者cpy, 则不要再操作，先去掉多余文件再拷贝" << endl;
	cout << "********* 1 :" << "将文件添加打印" << endl;
	cout << "********* 2 :" << "将文件去掉打印" << endl;
	cout << "********* 3 :" << "去掉多余文件" << endl;

	int cmd = 3; // default 0

	while (1) {
		cout << "请输入命令:";
		cin >> cmd;

		//if (argc > 1) {
		//	cmd = atoi(argv[1]);
		//}

		CopyAllFiles(baseFilePath, cmd);

		allFileNameAndPath.close(); // 保留编译的

	}
	return 0;
}